package com.kiwi.util;

import com.caucho.hessian.io.Hessian2Input;
import com.kiwi.constant.Constant;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.util.Set;



/*
为了防止由于环境导致的redis库的问题，降低频繁切换reids的开销，降低排查bug成本
redis的host现在强依赖被测系统，即测test1的api就连test1的redis
 */
public class RedisUtil {
    private JedisPool pool;
    private static Logger logger = Logger.getLogger(RedisUtil.class);

    public RedisUtil(String host, int port) {
        this(new JedisPoolConfig(), host, port);
    }

    public RedisUtil(String host, int port, int timeout) {
        this(new JedisPoolConfig(), host, port, null, null, 0, timeout);
    }

    public RedisUtil(JedisPoolConfig poolConfig, String host, int port) {
        this(poolConfig, host, port, null, null, 0, 2000);
    }

    public RedisUtil(JedisPoolConfig poolConfig, String host, int port, String clientName, String password, int database, int timeout) {
        this.pool = new JedisPool(poolConfig, getRedisAddress(), port, Constant.REDIS_TIME_OUT, Constant.REDIS_PASSWORD, database, clientName);
    }

    public RedisUtil(JedisPoolConfig poolConfig, String host, int port, String clientName, String password, int database, int timeout, boolean usehost) {
        if (usehost) {
            this.pool = new JedisPool(poolConfig, host, port, Constant.REDIS_TIME_OUT, Constant.REDIS_PASSWORD, database, clientName);
        } else {
            this.pool = new JedisPool(poolConfig, getRedisAddress(), port, Constant.REDIS_TIME_OUT, Constant.REDIS_PASSWORD, database, clientName);
        }
    }

    private JedisPool getPool() {
        return this.pool;
    }

    /*
    动态获取redis ip
     */
    public static String getRedisAddress() {
        InetAddress[] array = HostUtil.gerServerIp(Constant.APIURLPreview);
        if (array == null) return null;
        String ip = array[0].getHostAddress();
        return Constant.REDIS_IP_MAP.get(ip);
    }

    public Object hessian2Deserialize(byte[] bytes) throws IOException {
        ByteArrayInputStream bin = null;
        if (bytes == null) {
            return null;
        }
        Object arg3;
        try {
            bin = new ByteArrayInputStream(bytes);
            Hessian2Input e = new Hessian2Input(bin);
            Object obj = e.readObject();
            e.close();
            arg3 = obj;
        } catch (IOException arg12) {
            logger.error("IOException while hessianReadObject:", arg12);
            throw arg12;
        } finally {
            try {
                bin.close();
            } catch (IOException arg11) {
                logger.error("IOException while hessianReadObject final:", arg11);
            }

        }

        return arg3;
    }

    public Object hessianGet(String key) {
        Jedis jedis = null;
        if (null == key) {
            return null;
        } else {
            try {
                jedis = pool.getResource();
                byte[] e = key.getBytes("UTF-8");
                byte[] valueBytes = jedis.get(e);
                return null == valueBytes ? null : hessian2Deserialize(valueBytes);
            } catch (UnsupportedEncodingException arg3) {
                pool.returnBrokenResource(jedis);
                logger.error("Error hessianGet object，key:" + key, arg3);
                return null;
            } catch (IOException arg4) {
                pool.returnBrokenResource(jedis);
                logger.error("Error hessianGet object，key:" + key, arg4);
                return null;
            } finally {
                if (null != pool) {
                    pool.returnResource(jedis);
                }
            }
        }
    }

    public Jedis getJedis(String environment) {
        return getJedis();
    }

    public Jedis getJedis() {
        Jedis jedis = this.getPool().getResource();
        return jedis;
    }

//    public static void close() {
//        if (jedis != null) {
//            pool.returnResource(jedis);
//        }
//    }

    public String get(String key) {
        Jedis jedis = null;
        String value = null;
        try {
            jedis = pool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            if (null != pool) {
                pool.returnResource(jedis);
            }
        }
        return value;
    }
    public String del(String key) {
        Jedis jedis = null;
        String value = null;
        try {
            jedis = pool.getResource();
            value = jedis.del(key).toString();
        } catch (Exception e) {
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            if (null != pool) {
                pool.returnResource(jedis);
            }
        }
        return value;
    }
    public String set(String key, String value,long expireSeconds) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            return jedis.setex(key, (int)expireSeconds, value);
        } catch (Exception e) {
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
            return "0";
        } finally {
            if (null != pool) {
                pool.returnResource(jedis);
            }
        }
    }

    public Object getObject(String key) {
        Jedis jedis = null;
        Object obj = null;
        try {
            jedis = pool.getResource();
            obj = this.hessian2Deserialize(jedis.get(key.getBytes()));
        } catch (Exception e) {
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            if (null != pool) {
                pool.returnResource(jedis);
            }
        }
        return obj;
    }

    public Set<String> zrange(String key, long start, long end) {
        Jedis jedis = null;
        Set<String> value = null;
        try {
            jedis = pool.getResource();
            value = jedis.zrange(key, start, end);
        } catch (Exception e) {
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            if (null != pool) {
                pool.returnResource(jedis);
            }
        }
        return value;
    }

    public JSONObject getJsonObj(String key) {
        return JSONObject.fromObject(getObject(key));
    }

    public boolean isConnectSuccess() {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            return jedis.isConnected() && jedis.ping().equals("PONG");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (null != pool) {
                pool.returnResource(jedis);
            }
        }
    }
}

//}
